﻿using System;
using NLog;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;

namespace CoreLibrary.JsonNet {

    public sealed class JSON {

        public static readonly JsonConverter IsoDateTimeConverter = new IsoDateTimeConverter();

        public static bool TrySerialize(object obj,
                                        out string result, 
                                        params JsonConverter[] converters) {
            try {
                result = Serialize(obj, converters);
                return true;
            } 
            catch (Exception) {
                result = null;
                return false;
            }
        }

        public static bool TryDeserialize<T>(string json, 
                                             out T result, 
                                             params JsonConverter[] converters) {
            try {
                result = Deserialize<T>(json, converters);
                return true;
            } 
            catch (Exception) {
                result = default(T);
                return false;
            }
        }

        public static string Serialize(object obj, params JsonConverter[] converters) {
            if (obj == null) {
                return string.Empty;
            }

            try {
                return JsonConvert.SerializeObject(obj, Formatting.None, 
                       new JsonSerializerSettings {
                           Converters = converters,    
                           DefaultValueHandling  = DefaultValueHandling.Ignore,
                           NullValueHandling     = NullValueHandling.Ignore,
                           MissingMemberHandling = MissingMemberHandling.Ignore
                       }
                );
            } catch (Exception exception) {
                var errorMsg = string.Format("serialize json error[{0}]", exception.Message);
                LogManager.GetCurrentClassLogger().ErrorException(errorMsg, exception);
                throw;
            }
        }

        public static T Deserialize<T>(string json, params JsonConverter[] converters) {
            if (string.IsNullOrEmpty(json)) {
                return default(T);
            }

            try {
                return JsonConvert.DeserializeObject<T>(json,
                    new JsonSerializerSettings {
                        Converters = converters,
                        DefaultValueHandling  = DefaultValueHandling.Ignore,
                        NullValueHandling     = NullValueHandling.Ignore,
                        MissingMemberHandling = MissingMemberHandling.Ignore
                    }
                 );
            } 
            catch (Exception exception) {
                var errorMsg = string.Format("deserialize json error[{0}], actual content[{1}]", exception.Message, json);
                LogManager.GetCurrentClassLogger().ErrorException(errorMsg, exception);
                throw;
            }
        }
    }
}